import 'package:shared_preferences/shared_preferences.dart';

/// 数据存储工具类
/// 键值对：key--value
class SharedPreferencesUtil {
  /// 字符串默认值
  static const String _DEFAULT_STRING_VALUE = "";

  /// 布尔默认值
  static const bool _DEFAULT_BOOL_VALUE = false;

  /// 双精度默认值
  static const double _DEFAULT_DOUBLE_VALUE = 0.0;

  /// 整型默认值
  static const int _DEFAULT_INT_VALUE = 0;

  /// 字符串列表默认值
  static const List<String> _DEFAULT_STRING_LIST_VALUE = [];

  /// 构造方法私有化
  SharedPreferencesUtil._();

  /// 静态实例
  static SharedPreferencesUtil _instance;

  /// 静态获取实例
  static SharedPreferencesUtil get instance => _getInstance();

  /// 获取 SharedPreferences 对象
  static SharedPreferencesUtil _getInstance() {
    if (_instance == null) {
      _instance = SharedPreferencesUtil._();
    }
    return _instance;
  }

  /// SharedPreferences 对象
  static SharedPreferences _preferences;

  /// 获取 SharedPreferences 对象
  static Future<SharedPreferences> _init() async {
    if (null == _preferences) {
      _preferences = await SharedPreferences.getInstance();
    }
    return _preferences;
  }

  /// 空方法，什么也不做
  void _() {}

  /// 存储键值
  /// @param key 键
  /// @param value 值
  void put(String key, dynamic value) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 存入数据
    if (value is bool) {
      await _preferences.setBool(key, value);
    } else if (value is double) {
      await _preferences.setDouble(key, value);
    } else if (value is int) {
      await _preferences.setInt(key, value);
    } else if (value is List<String>) {
      await _preferences.setStringList(key, value);
    } else {
      await _preferences.setString(key, value);
    }
  }

  /// 获取值
  /// @param key 键
  /// @param value 默认值
  /// @return 值
  dynamic get(String key, {dynamic value = _DEFAULT_STRING_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取值
    dynamic kValue = _preferences.get(key);
    // 判断是否为空
    if (null == kValue) {
      // 赋值
      kValue = value;
    }
    return kValue;
  }

  /// 获取布尔值
  /// @param key 键
  /// @param fun 回调方法
  /// @param value 默认值
  void getBool(String key, Function fun,
      {bool value = _DEFAULT_BOOL_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取布尔值
    var kValue = _preferences.getBool(key);
    // 判断是否为布尔值
    if (!(kValue is bool)) {
      // 如果不是则赋值默认值
      kValue = value;
    }
    // 回调
    fun(kValue);
  }

  /// 获取双精度值
  /// @param key 键
  /// @param fun 回调方法
  /// @param value 默认值
  void getDouble(String key, Function fun,
      {double value = _DEFAULT_DOUBLE_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取双精度值
    var kValue = _preferences.getDouble(key);
    // 判断是否为双精度值
    if (!(kValue is double)) {
      // 如果不是则赋值默认值
      kValue = value;
    }
    // 回调
    fun(kValue);
  }

  /// 获取整型值
  /// @param key 键
  /// @param fun 回调方法
  /// @param value 默认值
  void getInt(String key, Function fun,
      {int value = _DEFAULT_INT_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取整型值
    var kValue = _preferences.getInt(key);
    // 判断是否为整型值
    if (!(kValue is int)) {
      // 如果不是则赋值默认值
      kValue = value;
    }
    // 回调
    fun(kValue);
  }

  /// 获取字符串值
  /// @param key 键
  /// @param fun 回调方法
  /// @param value 默认值
  void getString(String key, Function fun,
      {String value = _DEFAULT_STRING_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取字符串值
    var kValue = _preferences.getString(key);
    // 判断是否为字符串值
    if (!(kValue is String)) {
      // 如果不是则赋值默认值
      kValue = value;
    }
    // 回调
    fun(kValue);
  }

  /// 获取字符串列表值
  /// @param key 键
  /// @param fun 回调方法
  /// @param value 默认值
  void getStringList(String key, Function fun,
      {List<String> value = _DEFAULT_STRING_LIST_VALUE}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 获取字符串列表值
    var kValue = _preferences.getStringList(key);
    // 判断是否为字符串列表值
    if (!(kValue is List<String>)) {
      // 如果不是则赋值默认值
      kValue = value;
    }
    // 回调
    fun(kValue);
  }

  /// 获取键值
  void getKeys(Function fun) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 回调方法
    fun(_preferences.getKeys());
  }

  /// 移除键值
  /// @param key 键
  /// @param fun 回调方法
  void remove(String key, {Function fun}) async {
    // 获取 SharedPreferences 对象
    _preferences == null ? await _init() : _();
    // 移除键值
    var isSuccess = await _preferences.remove(key);
    // 判断回调函数是否为空
    if (null != fun) {
      // 回调方法
      fun(isSuccess);
    }
  }
}
